<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
      <el-form-item label="发生时间">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          value-format="yyyy-MM-dd"
          @change="handleDateChange">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="类型">
        <el-select v-model="queryParams.type" clearable @change="handleQuery">
          <el-option label="全部" :value="undefined" />
          <el-option
            v-for="item in equipmentTypeOptions"
            :key="item.dictValue"
            :label="item.dictLabel"
            :value="item.dictValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="状态">
        <el-select v-model="queryParams.status" clearable @change="handleQuery">
          <el-option label="全部" :value="undefined" />
          <el-option
            v-for="item in statusOptions"
            :key="item.code"
            :label="item.name"
            :value="item.code"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="名称">
        <el-input v-model="queryParams.assetName" placeholder="请输入名称" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>

      <div v-show="!folded">
        <el-form-item label="资产编号">
          <el-input v-model="queryParams.assetNo" placeholder="请输入资产编号" clearable @keyup.enter.native="handleQuery"/>
        </el-form-item>
        <el-form-item label="使用部门">
          <el-input v-model="queryParams.deptId" placeholder="全部" clearable @keyup.enter.native="handleQuery"/>
        </el-form-item>
        <el-form-item label="报修类型">
          <el-select v-model="queryParams.reportType" clearable placeholder="请选择报修类型" @change="handleQuery">
            <el-option label="全部" value="" />
            <el-option
              v-for="item in reportTypeOptions"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="故障类型">
          <el-select v-model="queryParams.faultType" clearable placeholder="请选择故障类型" @change="handleQuery">
            <el-option label="全部" value="" />
            <el-option
              v-for="item in faultTypeOptions"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="紧急程度">
          <el-select v-model="queryParams.urgency" clearable placeholder="请选择紧急程度" @change="handleQuery">
            <el-option label="全部" value="" />
            <el-option
              v-for="item in urgencyOptions"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
      </div>
      <el-form-item>
        <el-button type="primary" @click="handleQuery">搜索</el-button>
        <el-button @click="resetQuery">重置</el-button>
        <el-button type="text" @click="toggleFold">
          <i :class="folded ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"></i>
          {{ folded ? '展开' : '收起' }}
        </el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" @click="handleAdd" v-hasPermi="['system:fault-report:add']">添加</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true">
      <el-table-column prop="reportNo" label="报修单号" min-width="180" :show-overflow-tooltip="true" />
      <el-table-column prop="assetNo" label="资产编号" min-width="120" :show-overflow-tooltip="true" />
      <el-table-column label="类型" width="120">
        <template slot-scope="scope">
          <span v-if="typeName(scope.row.assetType || scope.row.type)">
            {{ typeName(scope.row.assetType || scope.row.type) }}
          </span>
          <span v-else class="empty-type">-</span>
        </template>
      </el-table-column>
      <el-table-column prop="assetName" label="名称" min-width="120" :show-overflow-tooltip="true" />
      <el-table-column prop="location" label="位置" min-width="120" :show-overflow-tooltip="true" />
      <el-table-column prop="deptName" label="使用部门" min-width="120" :show-overflow-tooltip="true" />
      <el-table-column prop="occurTime" label="发生时间" min-width="160" :show-overflow-tooltip="true" />
      <el-table-column prop="reporter" label="报修人" width="100" :show-overflow-tooltip="true" />
      <el-table-column prop="faultTypeName" label="故障类型" width="120" :show-overflow-tooltip="true" />
      <el-table-column label="紧急程度" width="120">
        <template slot-scope="scope">
          <el-tag
            :style="urgencyCustomStyle(scope.row)"
            effect="dark"
          >
            {{ scope.row.urgencyName || urgencyName(scope.row.urgency || scope.row.urgencyCode) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="状态" width="110">
        <template slot-scope="scope">
          <el-tag :type="statusType(scope.row.status, scope.row.statusName)">{{ statusName(scope.row.status, scope.row.statusName) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="200" fixed="right">
        <template slot-scope="scope">
          <el-button type="text" class="op-link view" @click="handleView(scope.row)" v-hasPermi="['system:fault-report:query']">查看</el-button>
          <el-button type="text" class="op-link edit" @click="handleEdit(scope.row)" v-if="canEdit(scope.row)">编辑</el-button>
          <el-button type="text" class="op-link submit" @click="handleSubmit(scope.row)" v-if="canSubmit(scope.row)">提交</el-button>
          <el-button type="text" class="op-link withdraw" @click="handleWithdraw(scope.row)" v-if="canWithdraw(scope.row)">撤回</el-button>
          <el-button type="text" class="op-link ok" @click="handleAcknowledge(scope.row)"
                     v-if="canAcknowledge(scope.row)" v-hasPermi="['system:fault-report:acknowledge']">承认</el-button>
          <el-button type="text" class="op-link warn" @click="handleReject(scope.row)"
                     v-if="canReject(scope.row)" v-hasPermi="['system:fault-report:reject']">{{ rejectLabel(scope.row) }}</el-button>
          <el-button type="text" class="op-link danger" @click="handleDelete(scope.row)" v-if="canDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>

<script>
import { listOrders, submitOrder, withdrawOrder, acknowledgeOrder, rejectOrder, delOrder } from '@/api/repair/order'
import request from '@/utils/request'
import RightToolbar from '@/components/RightToolbar/index.vue'
import store from '@/store'
// 导入字典相关的API
import { listReportType } from '@/api/dict/reportType'
import { listFaultType } from '@/api/dict/faultType'
import { listLevel } from '@/api/dict/level'

export default {
  name: 'OrderIndex',
  components: { RightToolbar },
  data() {
    return {
      loading: false,
      list: [],
      total: 0,
      dateRange: [],
      queryParams: { pageNum: 1, pageSize: 10 },
      // 显示搜索条件
      showSearch: true,
      // 折叠状态
      folded: true,
      // 设备类型选项
      equipmentTypeOptions: [],
      // 报修类型选项
      reportTypeOptions: [],
      // 故障类型选项
      faultTypeOptions: [],
      // 紧急程度选项
      urgencyOptions: [],
      // 状态选项
      statusOptions: [],
      statusMap: {},
      // 紧急程度字典映射：code -> name/type（动态加载，覆盖本地fallback）
      urgencyNameMap: {},
      urgencyTypeMap: {},
      urgencyColorMap: {}
    }
  },
  created() {
    // 仅在具备相应权限时加载字典，避免403
    const perms = (store && store.getters && store.getters.permissions) || []
    if (perms.includes('system:level:list')) this.loadUrgencyDict()
    if (perms.includes('system:type:list')) this.loadEquipmentTypeDict()
    // 确保始终尝试加载设备类型字典
    this.loadEquipmentTypeDict()
    // 确保始终尝试加载紧急程度字典
    this.loadUrgencyDict()
    // 加载报修类型、故障类型和紧急程度选项
    this.loadReportTypes()
    this.loadFaultTypes()
    this.loadUrgencyOptions()
    this.loadStatusOptions()
    this.getList()
  },
  methods: {
    // 拒绝按钮文案（兼容旧版“拒绝提交”）
    rejectLabel(row){
      if (row.status === 'DRAFT') return '拒绝提交'
      if (row.status === 'PENDING_ACKNOWLEDGE') return '拒绝提交'
      if (row.status === 'COMPLETED') return '拒绝承认'
      return '拒绝承认'
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.dateRange = [];
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        type: undefined,
        status: undefined,
        assetName: undefined,
        assetNo: undefined,
        deptId: undefined,
        reportType: undefined,
        faultType: undefined,
        urgency: undefined
      };
      this.handleQuery();
    },
    /** 切换搜索显示 */
    toggleSearch() {
      this.showSearch = !this.showSearch;
    },
    // 展开/收起搜索表单
    toggleFold() {
      this.folded = !this.folded;
    },
    // 处理日期变化
    handleDateChange(value) {
      if (value) {
        this.queryParams.params = {
          beginTime: value[0],
          endTime: value[1]
        };
      } else {
        this.queryParams.params = {};
      }
    },
    // 加载报修类型选项
    loadReportTypes() {
      listReportType({ pageNum: 1, pageSize: 9999, enabled: 1 }).then(res => {
        this.reportTypeOptions = res.rows || []
      }).catch(() => {})
    },
    // 加载状态选项：合并报修单与维修工单状态，避免出现未知
    async loadStatusOptions() {
      try {
        const [rptRes, workRes] = await Promise.all([
          request({ url: '/system/status/rpt-order/list', method: 'get', params: { pageNum: 1, pageSize: 9999, enabled: 1 } }),
          request({ url: '/system/status/work-order/list', method: 'get', params: { pageNum: 1, pageSize: 9999, enabled: 1 } })
        ])
        const listA = rptRes.rows || []
        const listB = workRes.rows || []
        const map = new Map()
        ;[...listA, ...listB].forEach(it => { if (it && it.code) map.set(it.code, { code: it.code, name: it.name }) })
        const fallback = [
          { code: 'ASSIGNED', name: '已指派' },
          { code: 'PENDING_EXEC', name: '待维修' },
          { code: 'IN_PROGRESS', name: '维修中' },
          { code: 'IN_REPAIR', name: '维修中' },
          { code: 'EXTRA_PROCESSING', name: '追加工中' },
          { code: 'EXTRA_PROCESS', name: '追加工中' },
          { code: 'EXTRA_PROC', name: '追加工中' },
          { code: 'EXTRA_PROCE', name: '追加工中' },
          { code: 'WAITING_MATERIAL', name: '待料中' },
          { code: 'DONE', name: '已完成' },
          { code: 'CANCELLED', name: '已取消' }
        ]
        fallback.forEach(it => { if (!map.has(it.code)) map.set(it.code, it) })
        const list = Array.from(map.values())
        this.statusOptions = list
        // 构建快速查找表
        const sMap = {}
        list.forEach(it => { sMap[it.code] = it.name })
        this.statusMap = sMap
      } catch (e) {
        // 兜底数据
        const list = [
          { code: 'DRAFT', name: '草稿' },
          { code: 'PENDING_ASSIGN', name: '待分配' },
          { code: 'PENDING_ACKNOWLEDGE', name: '待承认' },
          { code: 'ACKNOWLEDGED', name: '已承认' },
          { code: 'REJECTED', name: '已拒绝' },
          { code: 'IN_REPAIR', name: '维修中' },
          { code: 'CONFIRMED', name: '已确认' },
          { code: 'CLOSED', name: '已关闭' },
          { code: 'EXTRA_PROCESSING', name: '追加工中' },
          { code: 'EXTRA_PROCESS', name: '追加工中' },
          { code: 'EXTRA_PROC', name: '追加工中' },
          { code: 'EXTRA_PROCE', name: '追加工中' },
          { code: 'ASSIGNED', name: '已指派' },
          { code: 'PENDING_EXEC', name: '待维修' },
          { code: 'IN_PROGRESS', name: '维修中' },
          { code: 'WAITING_MATERIAL', name: '待料中' },
          { code: 'DONE', name: '已完成' },
          { code: 'CANCELLED', name: '已取消' }
        ]
        this.statusOptions = list
        const sMap = {}
        list.forEach(it => { sMap[it.code] = it.name })
        this.statusMap = sMap
      }
    },
    // 加载故障类型选项
    loadFaultTypes() {
      listFaultType({ pageNum: 1, pageSize: 9999, enabled: 1 }).then(res => {
        this.faultTypeOptions = res.rows || []
      }).catch(() => {})
    },
    // 加载紧急程度选项
    loadUrgencyOptions() {
      listLevel({ pageNum: 1, pageSize: 9999, enabled: 1 }).then(res => {
        this.urgencyOptions = res.rows || []
      }).catch(() => {})
    },
    // 加载设备类型字典数据
    async loadEquipmentTypeDict() {
      try {
        const res = await request({ url: '/system/type/list', method: 'get', params: { pageNum: 1, pageSize: 9999, enabled: 1 } })
        this.equipmentTypeOptions = (res.rows || []).map(item => ({
          dictValue: item.code,
          dictLabel: item.name
        }))
      } catch(e) { /* ignore */ }
    },
    // 加载"报修紧急程度"字典，读取颜色/标签类型
    async loadUrgencyDict() {
      try {
        const res = await request({ url: '/system/level/list', method: 'get', params: { pageNum: 1, pageSize: 999, enabled: 1 } })
        const rows = res.rows || []
        const nameMap = {}
        const typeMap = {}
        const colorMap = {} // 新增颜色映射
        rows.forEach(it => {
          const code = it.code || it.levelCode || it.dictCode
          const name = it.name || it.levelName || it.dictLabel
          // 颜色字段兼容：tagType/color/style/levelColor
          const t = it.tagType || it.color || it.style || it.levelColor
          if (code) nameMap[code] = name
          if (code && t) typeMap[code] = t
          // 处理颜色十六进制值
          if (code && it.colorHex) colorMap[code] = it.colorHex
        })
        this.urgencyNameMap = nameMap
        this.urgencyTypeMap = typeMap
        this.urgencyColorMap = colorMap // 保存颜色映射
        console.log('紧急程度字典数据:', { nameMap, typeMap, colorMap })
      } catch(e) {
        console.error('加载紧急程度字典失败:', e)
      }
    },
    getList() {
      // 处理日期范围查询
      if (this.dateRange && this.dateRange.length === 2) {
        this.queryParams.params = {
          beginTime: this.dateRange[0],
          endTime: this.dateRange[1]
        };
      } else {
        this.queryParams.params = {};
      }

      this.loading = true
      listOrders(this.queryParams).then(res => {
        this.list = res.rows || []
        this.total = res.total || 0
      }).finally(() => { this.loading = false })
    },
    // 紧急程度名与色
    urgencyName(code) {
      if (code && this.urgencyNameMap && this.urgencyNameMap[code]) return this.urgencyNameMap[code]
      const map = {
        URGENT: '紧急',
        HIGH: '较高',
        MEDIUM: '一般',
        LOW: '较低'
      }
      return map[code] || code || ''
    },
    urgencyType(code) {
      if (code && this.urgencyTypeMap && this.urgencyTypeMap[code]) return this.urgencyTypeMap[code]
      const map = {
        URGENT: 'danger',
        HIGH: 'warning',
        MEDIUM: 'info',
        LOW: 'success'
      }
      return map[code] || 'info'
    },
    // 兼容行级数据的多种字段，尽量匹配颜色
    urgencyTypeRow(row) {
      const name = row.urgencyName || ''
      if (name.includes('紧急')) return 'danger'
      if (name.includes('高')) return 'warning'
      if (name.includes('中')) return 'warning'
      if (name.includes('低')) return 'success'
      if (name.includes('计划')) return 'info'

      const code = String(row.urgency || row.urgencyCode || '')
      if (/URGENT_001|URGENT/i.test(code)) return 'danger'
      if (/URGENT_002|HIGH/i.test(code)) return 'warning'
      if (/URGENT_003|MEDIUM/i.test(code)) return 'warning'
      if (/URGENT_004|LOW/i.test(code)) return 'success'
      if (/URGENT_005|PLAN/i.test(code)) return 'info'
      return 'info'
    },
    // 获取自定义样式（基于颜色十六进制值）
    urgencyCustomStyle(row) {
      const code = String(row.urgency || row.urgencyCode || '')
      if (code && this.urgencyColorMap && this.urgencyColorMap[code]) {
        return {
          backgroundColor: this.urgencyColorMap[code],
          borderColor: this.urgencyColorMap[code],
          color: '#fff'
        }
      }
      return {}
    },
    handleAdd() {
      // 使用系统内置的新增报修逻辑：打开同页弹窗/或跳转既有新增页
      // 这里恢复为原版新增路由
      this.$router.push({ path: '/system/order-add' })
    },
    handleEdit(row) {
      this.$router.push({ path: `/system/order-edit/${row.reportNo}` })
    },
    handleView(row) {
      // 检查权限
      const hasPermission = this.$auth.hasPermi('system:fault-report:query');
      if (!hasPermission) {
        this.$message.warning('无查看权限')
        return
      }
      // 检查reportNo
      const no = row.reportNo || row.rptNo || row.report_no
      if (!no) {
        this.$message.error('无法获取报修单号')
        return
      }
      // 使用完整的路由对象而不是path
      this.$router.push({
        name: 'OrderDetail',
        params: { orderNo: no }
      }).catch(err => {
        console.error('Navigation error:', err);
        this.$message.error('页面跳转失败');
      });
    },
    handleSubmit(row) {
      this.$confirm('确认提交该故障报修单？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        submitOrder(row.reportNo).then(() => {
          this.$message.success('提交成功')
          this.getList()
        })
      })
    },
    handleWithdraw(row) {
      this.$confirm('确认撤回该故障报修单？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        withdrawOrder(row.reportNo).then(() => {
          this.$message.success('撤回成功')
          this.getList()
        })
      })
    },
    handleAcknowledge(row) {
      this.$confirm('确认承认该故障报修单？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        acknowledgeOrder(row.reportNo).then(() => {
          this.$message.success('承认成功')
          this.getList()
        })
      })
    },
    handleReject(row) {
      const isRejectSubmit = row.status === 'PENDING_ACKNOWLEDGE'
      const isDraftDelete = row.status === 'DRAFT'
      const title = isDraftDelete
        ? '确认删除该草稿报修单？'
        : (isRejectSubmit ? '确认拒绝提交该故障报修单？' : '确认拒绝承认该故障报修单？拒绝后将重新生成维修单。')
      this.$confirm(title, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (isDraftDelete) {
          delOrder(row.reportNo).then(() => {
            this.$message.success('已删除草稿')
            this.getList()
          })
        } else if (isRejectSubmit) {
          withdrawOrder(row.reportNo).then(() => {
            this.$message.success('已拒绝提交并撤回至草稿')
            this.getList()
          })
        } else {
          rejectOrder(row.reportNo).then(() => {
            this.$message.success('拒绝成功，已重新生成维修单')
            this.getList()
          })
        }
      })
    },
    handleDelete(row) {
      this.$confirm('确认删除该故障报修单？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delOrder(row.reportNo).then(() => {
          this.$message.success('删除成功')
          this.getList()
        })
      })
    },
    // 状态与归属判断
    isOwner(row) {
      const currentId = (store && store.getters && store.getters.id) || ''
      const currentName = (store && store.getters && store.getters.name) || ''
      return (row.reporterId && String(row.reporterId) === String(currentId)) || (row.reporter && row.reporter === currentName) || (row.createBy && String(row.createBy) === String(currentName))
    },
    hasAdminRole() {
      const roles = (store && store.getters && store.getters.roles) || []
      return Array.isArray(roles) && roles.includes('admin')
    },
    canEdit(row) {
      return row.status === 'DRAFT' && this.isOwner(row)
    },
    canSubmit(row) {
      // 仅在草稿状态显示提交按钮（不再限制为本人）
      return row.status === 'DRAFT'
    },
    canWithdraw(row) {
      return row.status === 'PENDING_ACKNOWLEDGE' && this.isOwner(row)
    },
    canAcknowledge(row) {
      // 只有已确认状态才显示承认按钮
      return row.status === 'CONFIRMED' && this.$auth.hasPermi('system:fault-report:acknowledge')
    },
    canReject(row) {
      // 只有已确认状态才显示拒绝承认按钮
      if (row.status === 'CONFIRMED') {
        return this.$auth.hasPermi('system:fault-report:reject')
      }
      // 场景2：待承认阶段可"拒绝提交"（恢复旧功能），管理员或具备同权限者可见
      if (row.status === 'PENDING_ACKNOWLEDGE') {
        return this.hasAdminRole() || this.$auth.hasPermi('system:fault-report:reject')
      }
      return false
    },
    canDelete(row) {
      // 按之前设计：草稿 或 已承认 可删除；需本人/管理员/有权限
      const allowStatus = row.status === 'DRAFT' || row.status === 'ACKNOWLEDGED'
      const allowActor = this.isOwner(row) || this.hasAdminRole() || this.$auth.hasPermi('system:fault-report:remove')
      return allowStatus && allowActor
    },
    statusName(code, name) {
      // 优先使用字典表映射
      if (code && this.statusMap && this.statusMap[code]) return this.statusMap[code]
      // 后端可能直接返回中文名称
      if (name && typeof name === 'string') return name
      if (code && typeof code === 'string') return code
      return '未知'
    },
    statusType(code, name) {
      const map = {
        DRAFT: 'info',
        PENDING_ASSIGN: 'warning',
        PENDING_ACKNOWLEDGE: 'warning',
        ACKNOWLEDGED: 'success',
        REJECTED: 'danger',
        IN_REPAIR: 'primary',
        CONFIRMED: 'warning',
        CLOSED: 'info',
        EXTRA_PROCESSING: 'danger',
        ASSIGNED: 'info',
        PENDING_EXEC: 'warning',
        IN_PROGRESS: 'primary',
        WAITING_MATERIAL: 'warning',
        DONE: 'success',
        CANCELLED: 'info'
      }
      if (map[code]) return map[code]
      // 兼容中文名称
      const cnMap = {
        '草稿': 'info',
        '待分配': 'warning',
        '待承认': 'warning',
        '已承认': 'success',
        '拒绝确认': 'danger',
        '维修中': 'primary',
        '已确认': 'warning',
        '已关闭': 'info',
        '追加工中': 'danger',
        '已指派': 'info',
        '待维修': 'warning',
        '待料中': 'warning',
        '已完成': 'success',
        '已取消': 'info'
      }
      if (name && cnMap[name]) return cnMap[name]
      return 'info'
    },
    // 根据设备类型编码显示中文名
    typeName(code) {
      // 处理空值情况
      if (!code) return '';

      // 确保设备类型选项已加载
      if (this.equipmentTypeOptions && this.equipmentTypeOptions.length > 0) {
        // 查找匹配的设备类型
        const type = this.equipmentTypeOptions.find(item => item.dictValue === code);
        // 如果找到匹配项，返回中文名称，否则返回原编码
        return type ? type.dictLabel : code;
      }

      // 如果字典数据未加载，返回编码本身
      return code;
    }
  }
}
</script>

<style scoped>
.op-link { margin-right: 8px; }
.op-link.view { color: #909399; }
.op-link.edit { color: #409EFF; }
.op-link.submit { color: #67C23A; }
.op-link.withdraw { color: #E6A23C; }
.op-link.ok { color: #67C23A; }
.op-link.warn { color: #E6A23C; }
.op-link.danger { color: #F56C6C; }
.empty-type { color: #999; }
</style>
